<?php
namespace PsiFramework\Applications\Bibliotheque\Classes\DAO;

import("Classes.DAO.AbstractDAO");
import("Applications.Bibliotheque.Classes.Model.Type");

use \PsiFramework\Classes\DAO\AbstractDAO;
use \PsiFramework\Applications\Bibliotheque\Classes\Model\Type;

/**
 * Bibliotheque
 * Gestion de ma bibliothèque
 *
 * @author Rémi San
 * @version beta
 */

/**
 * Classe d'accès à un Type
 *
 * @package DAO
 */
class TypeDAO extends AbstractDAO
{

    protected static $_singleton = null;

    protected $_listByParent ;

    protected function __construct($alias)
    {
        parent::__construct($alias);
        $this->_listByParent = array();
    }

    protected function getChildrenByParent(/*string*/ $key)
    {
        $this->_logger->debug(
            "Retrieving already requested children".
            " for the parent Type : " + $key
        );
        if (isset($this->_listByParent[$key])) {
            return $this->_listByParent[$key] ;
        } else {
            return null ;
        }
    }

    protected function setChildrenByParent(/*string*/ $key, /*array*/ $children)
    {
        $this->_logger->debug("Storing children for the parent Type : " + $key);
        $this->_listByParent[$key] = $children;
    }

    /**
     *  Retourne la liste des types racine
     *
     * @return      Type[]            Les Types
     */
    public function retrieveBaseTypes()
    {
        return $this->retrieveChildren(null);
    }

    /**
     * Retourne tous les Types enfants du type passé
     *
     * @param        Type            $parent
     * @return      Type[]            Les Types
     */
    public function retrieveChildren(/*Type*/ $parent)
    {

        $types = array();
        $parentId = (is_null($parent))?null:$parent->getId();

        if (!is_null($parent)) {
            $children = $parent->getChildren();
            if (!is_null($children)) return $children ;
        }

        $children = $this->getChildrenByParent($parentId);
        if (!is_null($children)) return $children ;

        $retrievedParent = $this->getRetrievedObject($parentId);
        if (!is_null($retrievedParent)) {
            $children = $retrievedParent->getChildren();
            if (!is_null($children)) return $children ;
        }

        $queryBuilder = new QueryBuilder();
        $queryBuilder->createSelectQuery();

        $table = new SqlTable("type", "bibliotheque");
        $queryBuilder->setTable($table);

        $columnParent = new SqlColumn("type_parent", $table);
        $columnNom = new SqlColumn("type_nom", $table);
        $value = new SqlValue($parentId);

        $equal = new SqlOperation(SqlOperation::$equal);
        $equal->addParameter($columnParent);
        $equal->addParameter($value);

        $queryBuilder->addWhereClause($equal);

        $paginator = new Paginator();
        $paginator->addOrder(new SqlOrder($columnNom));

        $queryBuilder->addPagination($paginator);

        $query = $queryBuilder->buildQuery();

        $result = $this->_database->executeQuery($query);

        if ($result) {
            while (($obj = $this->_database->getNextResult($result)) != null) {
                $this->_logger->debug(
                    'Retrieving new object from the query response.'
                );
                $type = self::getObjectFromSqlObject($obj);
                if (!is_null($type)) $types[] = $type ;
            }
        }
        $this->setChildrenByParent($parentId, $types);
        return $types;
    }

    /**
     * Function to be called instead of the constructor.
     *
     * @return TypeDAO instance
     */
    public static function getInstance($objectParameters)
    {

        if (self::$_singleton==null) {
            self::$_singleton = new TypeDAO($objectParameters);
        }

        return self::$_singleton;
    }
}
